package cn.lg.soar.cloud.core.config;

import cn.lg.soar.common.util.IpUtil;
import cn.lg.soar.common.util.data.DataUtil;
import cn.lg.soar.mvc.util.ResponseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest;

/**
 * 白名单拦截
 * @author luguoxiang
 */
public class FeignRequestConfig implements WebMvcConfigurer {

    protected static final Logger LOGGER = LoggerFactory.getLogger(FeignRequestConfig.class);

    @Autowired
    private CloudProperties properties;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        if (DataUtil.isValuable(properties.getSecret())) {
            InterceptorRegistration registration = registry
                    .addInterceptor(new FeignInterceptor(properties.getSecret().getBytes()))
                    .order(0);
            if (DataUtil.isValuable(properties.getIncludePaths())) {
                registration.addPathPatterns(properties.getIncludePaths());
            }
            if (DataUtil.isValuable(properties.getExcludePaths())) {
                registration.excludePathPatterns(properties.getExcludePaths());
            }
        }
    }

    /**
     * 白名单拦截器
     */
    public static class FeignInterceptor implements HandlerInterceptor {

        private final byte[] secret;

        public FeignInterceptor(byte[] secret) {
            this.secret = secret;
        }

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 准备数据
            String expire = request.getHeader("security-expire");
            String random = request.getHeader("security-random");
            String sign = request.getHeader("security-sign");
            if (expire == null || random == null || sign == null) {
                // 已过期
                LOGGER.warn("访问安全拦截，凭证无效，IP={}", IpUtil.getRemoteIp(request));
                ResponseUtils.E412(response, "访问安全拦截");
                return false;
            }
            if (System.currentTimeMillis() > Long.parseLong(expire)) {
                // 已过期
                LOGGER.warn("访问安全拦截，凭证失效，IP={}", IpUtil.getRemoteIp(request));
                ResponseUtils.E412(response, "访问安全拦截");
                return false;
            }
            // 数据验签
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(secret);
            digest.update(random.getBytes());
            digest.update(expire.getBytes());
            if (DataUtil.byteToHex(digest.digest()).equals(sign)) {
                return true;
            }
            // 验签失败
            LOGGER.warn("访问安全拦截，验签失败，IP={}", IpUtil.getRemoteIp(request));
            ResponseUtils.E412(response, "访问安全拦截");
            return false;
        }

    }


}
